﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Calculator c = new Calculator();
            c.run();
        }
    }

    class Calculator
    {
        public void run() {
            while (true) {
                Console.Write("请输入算式:");
                String s = Console.ReadLine();
                int result = this.caculate(s);
                Console.Write("结果为:"+result+"\n");
            }
        }

        public int caculate(String s) {
            int num = 0;
            int result = 0;
            Stack<int> nums = new Stack<int>();
            Stack<char> operate = new Stack<char>();
            for (int i = 0; i < s.Length; i++)
            {
                if ((int)s.ElementAt(i) >= 48 && (int)s.ElementAt(i) < 58)
                {
                    int at = (int)s.ElementAt(i) - 48;
                    num = num * 10 + at;
                    if (i == s.Length - 1)
                        nums.Push(num);
                }
                else if (s.ElementAt(i) == '+' || s.ElementAt(i) == '-' || s.ElementAt(i) == '*' || s.ElementAt(i) == '/' || s.ElementAt(i) == ')' || s.ElementAt(i) == '%' || s.ElementAt(i) == '|')
                {
                    nums.Push(num);
                    operate.Push(s.ElementAt(i));
                    num = 0;
                }
                else
                {
                    operate.Push(s.ElementAt(i));
                }
            }

            while (nums.Count != 1) {
                char o = operate.Pop();
                if (o == ')')
                {
                    int count = 0;
                    String sIn = "";
                    Stack<int> numsCopy = new Stack<int>();
                    Stack<char> operateCopy = new Stack<char>();
                    while (!(operate.Peek() == '(' && count == 0)) {
                        if (operate.Peek() == ')')
                            count++;
                        if (operate.Peek() == '(')
                            count--;
                        numsCopy.Push(nums.Pop());
                        operateCopy.Push(operate.Pop());
                        //sIn += (operate.Pop() + nums.Pop());
                    }
                    numsCopy.Push(nums.Pop());
                    operate.Pop();
                    sIn += numsCopy.Pop();
                    while (numsCopy.Count != 0) {
                        sIn = sIn + operateCopy.Pop() + numsCopy.Pop();
                    }
                    nums.Push(this.caculate(sIn));
                }
                else if ((operate.Count!=0) && (o == '+' || o == '-') && (operate.Peek() == '*' || operate.Peek() == '/'))
                {
                    int numr = nums.Pop();
                    int numm = nums.Pop();
                    int numl = nums.Pop();
                    char operater = operate.Pop();
                    char operatel = operate.Pop();
                    nums.Push(this.twoNumberCalculate(operatel, numl, numm));
                    nums.Push(numr);
                    operate.Push(operater);
                }
                else {
                    int numb = nums.Pop();
                    int nump = nums.Pop();
                    result = this.twoNumberCalculate(o, nump, numb);
                    nums.Push(result);
                }
            }
            return result;
        }

        public int twoNumberCalculate(char operate, int nump, int numb) {
            int result = 0;
            switch (operate)
            {
                case '+': result = this.add(nump, numb);break;
                case '-': result = this.decrease(nump, numb);break;
                case '*': result = this.multiply(nump, numb);break;
                case '/': result = this.divide(nump, numb);break;
                case '%': result = this.remainder(nump, numb); break;
                case '|': result = this.bitAnd(nump, numb); break; 
            }
            return result;
        }

        public int add(int n1, int n2) {
            int number = n1 + n2;
            return number;
        }

        public int decrease(int n1, int n2) {
            int number = n1 - n2;
            return number;
        }

        public int multiply(int n1, int n2)
        {
            int number = n1 * n2;
            return number;
        }

        public int divide(int n1, int n2)
        {
            int number = n1 / n2;
            return number;
        }

        public int remainder(int n1, int n2) {
            int remainder = n1 % n2;
            return remainder;
        }

        public int bitAnd(int n1, int n2) {
            String bn1 = Convert.ToString(n1, 2);
            String bn2 = Convert.ToString(n2, 2);
            int end = 0;
            int lenth = Math.Min(bn2.Length, bn1.Length);
            char[] bresult = new char[lenth];
            for (int i = Math.Min(bn1.Length, bn2.Length) - 1; i >= 0; i--) {
                if (bn1[i]-48 > 0 && bn2[i]-48 > 0)
                {
                    bresult[i] = '1';
                }
                else {
                    bresult[i] = '0';
                }
            }
            String result = new String(bresult);
            return Convert.ToInt32(result, 2);
        }
    }

}
